/*
File:		Entity.cpp
Course:		SGD 1301
Author:		dmonroe
Purpose:	CEntity class is the base class for
moving entities
*/

#include "Entity.h"

#include "../SGD Wrappers/CSGD_TextureManager.h"

#include <cassert>


////////////////////////////////////////////////////////////
// CONSTRUCTOR
CEntity::CEntity( void )
{
	// Set the entity's type
	m_eType		= ENT_BASE;

	// Set the data members to 'clean' values
	m_fPosX		= 0;	// top-left corner
	m_fPosY		= 0;

	m_fVelX		= 0;
	m_fVelY		= 0;

	m_nWidth	= 1;
	m_nHeight	= 1;

	m_nImageID	= -1;

	m_unRefCount	= 1;

	m_pTarget = nullptr;
}


////////////////////////////////////////////////////////////
// DESTRUCTOR
CEntity::~CEntity(void)
{
	if(m_pTarget!=nullptr)
	{
		m_pTarget->Release();
		m_pTarget = nullptr;
	}
}

////////////////////////////////////////////////////////////
// Update		- move the entity
/*virtual*/ void CEntity::Update( float fElapsedTime )
{
	m_fPosX	+= m_fVelX * fElapsedTime;
	m_fPosY += m_fVelY * fElapsedTime;
}

////////////////////////////////////////////////////////////
// Render		- draw the entity
/*virtual*/ void CEntity::Render( void )
{
	// assert will display a message box if the condition FAILS
	// (only in Debug mode)
	assert( m_nImageID != -1 && "CEntity::Render - invalid image id!" );


	CSGD_TextureManager::GetInstance()->Draw( m_nImageID,
		(int)GetPosX(), (int)GetPosY() );
}


////////////////////////////////////////////////////
// GetRect
//	- returns the entity's bounding rectangle
/*virtual*/ RECT CEntity::GetRect( void ) const
{
	RECT rSelf = 
	{
		(LONG)GetPosX(),
		(LONG)GetPosY(),
		(LONG)(GetPosX() + GetWidth()),
		(LONG)(GetPosY() + GetHeight())
	};

	return rSelf;
}

////////////////////////////////////////////////////
// CheckCollision
//	- returns true if the entities are overlapping
/*virtual*/ bool CEntity::CheckCollision( IEntity* pOther )
{
	RECT rSelf	= this->GetRect();
	RECT rOther	= pOther->GetRect();
	RECT rOverlap;

	return ( IntersectRect( &rOverlap, &rSelf, &rOther ) == TRUE );
}


////////////////////////////////////////////////////////////
// AddRef		- increase the reference count
/*virtual*/ void CEntity::AddRef( void )
{
	assert( m_unRefCount != UINT_MAX && "CEntity::AddRef - maximum number of references reached" );

	++m_unRefCount;
}

////////////////////////////////////////////////////////////
// Release		- decrease the reference count
//				- self-destruct when the count reaches 0
/*virtual*/ void CEntity::Release( void )
{
	--m_unRefCount;

	if( m_unRefCount == 0 )
		delete this;
}

void CEntity::SetTarget ( CEntity* Target )	
{	
	if(m_pTarget != nullptr)
		m_pTarget->Release();
	m_pTarget = Target;	
	m_pTarget->AddRef();	
}


void CEntity::rotate_point(float cx, float cy, float angle, POINT& p)
{
	float s = sin(angle);
	float c = cos(angle);

	p.x -= (LONG)cx;
	p.y -= (LONG)cy;

	float xnew = p.x * c - p.y * s;
	float ynew = p.x * s + p.y * c;

	p.x = (LONG)(xnew + cx);
	p.y = (LONG)(ynew + cy);
}
